Package huu.phong.musiconline.audio

Source Code of huu.phong.musiconline.audio.AudioPlayer

package huu.phong.musiconline.audio;

import huu.phong.musiconline.model.AudioInfo;
import huu.phong.musiconline.model.ISong;
import huu.phong.musiconline.sites.Site;
import huu.phong.musiconline.utils.Utils;

import java.util.Stack;

import javax.sound.sampled.AudioFormat;
import javax.sound.sampled.AudioSystem;
import javax.sound.sampled.DataLine;
import javax.sound.sampled.Line;
import javax.sound.sampled.LineUnavailableException;
import javax.sound.sampled.SourceDataLine;

public class AudioPlayer {
  private AudioStream in;
  private byte[] buffer = new byte[32768];
  private boolean stoped = false;
  private SourceDataLine source;
  private AudioFormat fmtTarget;
  private boolean paused = false;
  private AudioPlayerListener listener;
  private int reading = -1;
  private AudioDecoder decoder;
  private int plusDuration = 0;
  private Streaming streaming;
  private AudioInfo audioInfo;
  private Object locked = new Object();
  private Stack<Thread> threads = new Stack<Thread>();
  private Thread processPlay;
  private boolean playing = false;
  private boolean repeat = false;
 
  public AudioPlayer(){
    listener = new AudioPlayerListener() {
     
      @Override
      public void playing(AudioPlayer player) {
      }
     
      @Override
      public void paused(AudioPlayer player) {
      }
     
      @Override
      public void init(AudioPlayer player) {
      }
     
      @Override
      public void finished(AudioPlayer player) {
      }

      @Override
      public void error(String error) {
       
      }
    };
    streaming = new Streaming() {
     
      @Override
      public void buffering(int length) {
      }
    };
    processPlay = new Thread(){
      public void run(){
        while (true){
          while (!threads.isEmpty()){
            Thread thread = threads.lastElement();
            if (thread.equals(threads.lastElement())){
              threads.clear();
              thread.start();
            } else {
              AudioPlayer.this.stop();
              continue;
            }
            try {
              thread.join();
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
          synchronized (locked) {
            try {
              locked.wait();
            } catch (InterruptedException e) {
              e.printStackTrace();
            }
          }
        }
      }
    };
    processPlay.start();
  }
 
  public void setListener(AudioPlayerListener listener){
    this.listener = listener;
  }
 
  public void setStreaming(Streaming streaming){
    this.streaming = streaming;
  }
 
  private void prepare(ISong song){
    try {
      if (song.getSite().equals(Site.MY_COMPUTER)){
        in = new FileAudioStream(song);
      } else {
        in = new SmartSeekAudioStream(song, streaming);
      }
    } catch (Exception e) {
      throw new RuntimeException(e.getMessage());
    }
    switch (in.getType()) {
    case AudioCodec.MP3_STREAM:
      decoder = new MP3FileDecoder(in);
      break;
     
    case AudioCodec.FLAC_STREAM:
      decoder = new FLACFileDecoder(in);
      break;
     
    case AudioCodec.WAV_STREAM:
      decoder = new WavFileDecoder(in);
      break;
     
    default:
      throw new RuntimeException("Not support this file type");
    }
    audioInfo = decoder.getAudioInfo();
    listener.init(this);
  }
 
  public int getBuffering(){
    if (in == null) return 0;
    return in.getBufferingValue();
  }
 
  public int getLength(){
    if (in == null) return 0;
    return in.getLength();
  }
 
  public boolean isBuffered(){
    if (in == null) return false;
    return in.isCompleted();
  }
 
  public void seek(int size){
    if (source == null) return;
    source.stop();
    source.close();
    plusDuration = sizeToDuration(size);
    decoder.seek(size);
    try {
      source.open(fmtTarget);
    } catch (LineUnavailableException e) {
      e.printStackTrace();
    }
    source.start();
  }
 
  public void play(final ISong song){
    stop();
    threads.add(new Thread(){
      public void run(){
        try {
          prepare(song);
        } catch (Exception e) {
          AudioPlayer.this.stop();
          listener.finished(AudioPlayer.this);
          listener.error(e.getMessage());
          return;
        }
        play();
      }
    });
    synchronized (locked) {
      locked.notifyAll();
    }
  }
 
  private synchronized void play(){
    createSource();
    stoped = false;
    plusDuration = 0;
    while (!stoped){
      reading = decoder.getPCMData(buffer);
      if (reading == -1){
        if(!repeat) break;
        seek(0);
        continue;
      }
      if (paused){
        synchronized (source) {
          source.stop();
          listener.paused(AudioPlayer.this);
          try {
            source.wait();
            source.start();
          } catch (InterruptedException e) {
            e.printStackTrace();
          }
        }
      }
      if(!stoped) listener.playing(AudioPlayer.this);
      source.write(buffer, 0, reading);
    }
    if (in != null){
      in.closeStream();
    }
    if(!stoped){
      source.drain();
      listener.playing(AudioPlayer.this);
    }
    source.flush();
    source.close();
    source = null;
    decoder = null;
    if (!stoped) listener.finished(AudioPlayer.this);
    stoped = true;
  }
 
  private void createSource(){
    fmtTarget = decoder.getAudioFormat();
    try {
      Line line = AudioSystem.getLine(new DataLine.Info(SourceDataLine.class, fmtTarget));
      if (line instanceof SourceDataLine) {
        source = (SourceDataLine) line;
        source.open(fmtTarget);
        source.start();
      }
    } catch (LineUnavailableException e) {
      e.printStackTrace();
    }
  }
 
  public void stop(){
    if (paused) resume();
    stoped = true;
  }
 
  public void pause(){
    paused = true;
  }
 
  public void resume(){
    if (source == null) return;
    paused = false;
    synchronized (source) {
      source.notify();
    }
  }
 
  public int getDuration(){
    if (decoder == null) return 0;
    return decoder.getDuration();
  }
 
  public AudioInfo getAudioInfo(){
    if (decoder == null) return new AudioInfo();
    return audioInfo;
  }
 
  public int getCurrentDuration(){
    if (source == null) return 0;
    return (int) (plusDuration + (source.getMicrosecondPosition() / 1000));
  }
 
  public String getPlayingDuration(){
    return Utils.toDuaration(getCurrentDuration()) + " / " + Utils.toDuaration(getDuration());
  }
 
  public String getPlayingInfo(){
    return "[" + getAudioInfo() + " | " + getPlayingDuration() + "]";
  }
 
  public int durationToSize(int duration){
    if (decoder == null) return 0;
    return decoder.durationToSize(duration);
  }
 
  public int sizeToDuration(int size){
    if (decoder == null) return 0;
    return decoder.sizeToDuration(size);
  }
 
  public void release(){
    if (in != null){
      in.closeStream();
      in.release();
    }
  }
 
  public int getCurrentSize(){
    if (in == null) return 0;
    return in.getCurrentPosition();
  }
 
  public boolean isPaused() {
    return paused;
  }
 
  public boolean isPlaying(){
    return playing;
  }
 
  public void setRepeat(boolean repeat){
    this.repeat = repeat;
  }
}
TOP

Related Classes of huu.phong.musiconline.audio.AudioPlayer

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.